#include "GLES2DepthBuffer.h"
#include "GLES2HardwarePixelBuffer.h"
#include "GLES2RenderSystem.h"
#include "GLES2FrameBufferObject.h"

namespace PVM
{
	GLES2DepthBuffer::GLES2DepthBuffer(uint16 poolId, GLES2RenderSystem* renderSystem, GLES2Context* creatorContext,
									   GLES2RenderBuffer* depth, GLES2RenderBuffer* stencil,
									   uint32 width, uint32 height, uint32 fsaa, uint32 multiSampleQuality,
									   bool isManual) :
	DepthBuffer(poolId, 0, width, height, fsaa, "", isManual),
	mMultiSampleQuality(multiSampleQuality),
	mCreatorContext(creatorContext),
	mDepthBuffer(depth),
	mStencilBuffer(stencil),
	mRenderSystem(renderSystem)
	{
		if (mDepthBuffer)
		{
			switch (mDepthBuffer->getGLFormat())
			{
				case GL_DEPTH_COMPONENT16:
					mBitDepth = 16;
					break;
				case GL_DEPTH_COMPONENT24_OES:
				case GL_DEPTH24_STENCIL8_OES:
					mBitDepth = 32;
					break;
			}
		}
	}
	
	GLES2DepthBuffer::~GLES2DepthBuffer()
	{
		if (mStencilBuffer && mStencilBuffer != mDepthBuffer)
		{
			delete mStencilBuffer;
			mStencilBuffer = 0;
		}
		
		if (mDepthBuffer)
		{
			delete mDepthBuffer;
			mDepthBuffer = 0;
		}
	}
	
	bool GLESDepthBuffer::isCompatible(RenderTarget* renderTarget) const
	{
		bool retVal = false;
		
		if (mRenderSystem->getCapabilities()->hasCapability(RSC_RTT_DEPTHBUFFER_RESOLUTION_LESSEQUAL))
		{
			if (!DepthBuffer::isCompatible(renderTarget))
				return false;
		}
		else
		{
			if (this->getWidth() != renderTarget->getWidth() ||
				this->getHeight() != renderTarget->getHeight() ||
				this->getFsaa() != renderTarget->getFSAA())
				return false;
		}
		
		GLES2FrameBufferObject* fbo = 0;
		renderTarget->getCustomAttribute("FBO", &fbo);
		
		if (!fbo)
		{
			GLES2Context* windowContext;
			renderTarget->getCustomAttribute("GLCONTEXT", &windowContext);
			
			if (!mDepthBuffer && !mStencilBuffer && mCreatorContext == windowContext)
				retVal = true;
		}
		else
		{
			if (mDepthBuffer || mStencilBuffer)
			{
				GLenum internalFormat = fbo->getFormat();
				GLenum depthFormat, stencilFormat;
				mRenderSystem->_getDepthStencilFormatFor(internalFormat, &depthFormat, &stencilFormat);
				
				bool bSameDepth = false;
				if (mDepthBuffer)
					bSameDepth |= mDepthBuffer->getGLFormat() == depthFormat;
				bool bSameStencil = false;
				if (!mStencilBuffer || mStencilBuffer == mDepthBuffer)
					bSameStencil = stencilFormat == GL_NONE;
				else
				{
					if (mStencilBuffer)
						bSameStencil = stencilFormat == mStencilBuffer->getGLFormat();
				}
				
				retVal = bSameDepth && bSameStencil;
			}
		}
		
		return retVal;
	}
}
